<?php

namespace services\baibai;

use common\models\base\Profession;
use Yii;
use common\models\patient\MonthRevisitingRecord;
use common\models\patient\RevisitingRecord;
use common\models\clinic\Clinic;
use common\models\base\BodyParts;
use common\models\base\PatientDiseases;
use common\models\clinic\Project;
use common\models\clinic\TreatmentRoom;
use common\models\member\Attr;
use common\models\member\Member;
use common\models\patient\ConsumptionDetail;
use common\models\clinic\UserTreatmentDetail;
use common\models\clinic\UserSurplus;
use common\models\clinic\UserTreatment;
use common\models\patient\ClinicRecord;
use common\models\patient\Consumption;
use common\models\patient\MedicalRecords;
use common\models\patient\User;
use common\models\baibai\Model;
use common\components\Service;
use yii\db\Expression;

/**
 * 白白管家数据更新
 *
 * Class UpdateDataMigrateService
 * @package services\baibai
 */
class UpdateDataMigrateService extends Service
{
    public static $projectId = 13;
    public static $outpatientTypeId = 1000;

    /**
     * 全部数据
     */
    public static function allData($params)
    {
        $lastPatient = User::find()
            ->select('id')
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        $lastPatientId = 0;
        if ($lastPatient && $lastPatient['id']) {
            $lastPatientId = $lastPatient['id'];
        }

        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 患者治疗
            self::treat($params);

            // 患者治疗项目
            self::userSurplus($params);

            // 患者消费记录表
            self::patientConsumption($params);

            // 患者就诊记录表(患者到院)
            self::clinicRecord($lastPatientId, $params);

            // 患者病历数据
            self::case($lastPatientId, $params);

            // 同步患者数据
            self::patient($lastPatientId, $params);

            // 患者消费、来院记录表
            self::patientRevisitingRecordBill($params);
            // 治疗、来院记录表
            self::patientRevisitingRecordTreat($params);
            // 更新是否统计
            self::updateIsSum($params);

            $transaction->commit();
        } catch (\Exception $exception) {
            $transaction->rollBack();
            throw new \Exception($exception->getMessage(), 500);
        }
    }

    /**
     * 同步患者数据
     * @Interface patient
     */
    public static function patient($lastPatientId, $params)
    {
        Model::setTableName('bm_patient');

        $whereArr = ['or'];
        $whereArr[] = ['between', 'created_at', $params['start_time'], $params['end_time']];
        $whereArr[] = ['between', 'updated_at', $params['start_time'], $params['end_time']];
        $whereArr[] = ['between', 'recept_time', $params['start_time'], $params['end_time']];
        $baiPatient = Model::find()->where($whereArr)->asArray()->all();

        $addList = [];
        foreach ($baiPatient as $val) {
            $patientUserIs = User::findOne(['patient_card_id' => $val['treat_no']]);
            // 患者不存在直接新增
            if (!$patientUserIs) {
                $add['id'] = $lastPatientId + $val['id'];
                $add['project_id'] = self::$projectId;
                $add['patient_card_id'] = $val['treat_no'];
                $add['name'] = $val['real_name'];
                $add['birthday'] = $val['birth_date'];

                $add['age'] = self::getAgeByBirthDate($val['birth_date']);
                $add['wx_name'] = ''; //
                $add['nickname'] = ''; //
                $add['source_channel_id'] = 0;
                $add['gender'] = $val['gender'];

                $add['mobile'] = trim($val['phone']);
                $add['city_id'] = $val['city_id'];
                $add['city_name'] = $val['city_name'];
                $add['address'] = $val['address'];
                $add['patient_diseases_id'] = self::getPatientDisease($val['id']);

                // $add['patient_body_parts_name'] = self::getPatientBodyParts($val['id']);
                $add['last_clinic_time'] = self::getPatientLastClinicTime($val['id']);
                $add['clinic_id'] = self::getPatientClinicOrReg($val['id'], 1);

                // 医助归属人随机分，随机获取医助id
                $medical_member_id_list = Attr::find()
                    ->select('member_id')
                    ->where([
                        'project_id' => self::$projectId,
                        'profession_id' => Profession::ID_MEDICAL,
                        'clinic_id' => $add['clinic_id']
                    ])
                    ->column();
                $randNum = rand(0, count($medical_member_id_list));
                if ($randNum == count($medical_member_id_list)) {
                    $randNum = 0;
                }
                $medical_member_id_list = array_unique($medical_member_id_list);
                $add['belong_assistant_id'] = $medical_member_id_list ? $medical_member_id_list[$randNum] : 0;

                $add['reg_time'] = self::getPatientClinicOrReg($val['id'], 2);

                $val['recept_time'] = $val['recept_time'] ? $val['recept_time'] : $val['created_at'];
                $add['last_revisiting_time'] = $val['recept_time'];

                $today = strtotime(date('Y-m-d', time()));
                $receptDay = strtotime(date('Y-m-d', $val['recept_time']));
                $add['missed_days'] = ($today - $receptDay) / 86400;

                $add['revisiting_count'] = self::patientRevisitingCount($val['id']);
                $add['status'] = 1;
                $add['modify_time'] = 0;
                $add['outpatient_type_id'] = self::$outpatientTypeId; // 患者就诊状态最初为初诊
                $add['created_at'] = time();
                $add['updated_at'] = time();
                $addList[] = $add;
            } else {
                $patientUserIs = User::findOne(['patient_card_id' => $val['treat_no']]);
                // 存在需要更新
                $patientUserIs->age = self::getAgeByBirthDate($val['birth_date']);
                $patientUserIs->mobile = trim($val['phone']);
                $patientUserIs->city_id = $val['city_id'];
                $patientUserIs->city_name = $val['city_name'];
                $patientUserIs->address = $val['address'];
                $patientUserIs->patient_diseases_id = self::getPatientDisease($val['id']);
                // $patientUserIs->patient_body_parts_name = self::getPatientBodyParts($val['id']);
                $patientUserIs->last_clinic_time = self::getPatientLastClinicTime($val['id']);
                $patientUserIs->clinic_id = self::getPatientClinicOrReg($val['id'], 1);


                // 上次有效消费时间
                Model::setTableName('bm_bill');
                $baiPatientBill = Model::find()
                    ->select('reception_time')
                    ->where([
                        'patient_appoint_info_id' => 0,
                        'status' => 1,
                        'patient_id' => $val['id'],
                    ])
                    ->orderBy(['id' => SORT_DESC])
                    ->asArray()
                    ->one();

                // 上次有效治疗时间
                Model::setTableName('bm_treat');
                $baiPatientTreat = Model::find()
                    ->select('finished_at')
                    ->where([
                        'status' => 1,
                        'patient_id' => $val['id'],
                    ])
                    ->orderBy(['id' => SORT_DESC])
                    ->asArray()
                    ->one();
                $lastRevisitingTime = 0;
                if ($baiPatientBill) {
                    $lastRevisitingTime = $baiPatientBill['reception_time'];
                }
                if ($baiPatientTreat) {
                    $lastRevisitingTime = $lastRevisitingTime > $baiPatientTreat['finished_at'] ? $lastRevisitingTime : $baiPatientTreat['finished_at'];
                }
                // 取消费、治疗的最近时间
                if ($lastRevisitingTime) {
                    $patientUserIs->last_revisiting_time = $lastRevisitingTime;
                }

                $today = strtotime(date('Y-m-d', time()));
                $receptDay = strtotime(date('Y-m-d', $val['recept_time']));
                $patientUserIs->missed_days = ($today - $receptDay) / 86400;

                $patientUserIs->revisiting_count = self::patientRevisitingCount($val['id']);

                if (!$patientUserIs->save()) {
                    throw new \Exception(json_encode($patientUserIs->errors), 500);
                }
            }

        }

        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(User::tableName(),
                    [
                        'id', 'project_id', 'patient_card_id', 'name', 'birthday',
                        'age', 'wx_name', 'nickname', 'source_channel_id', 'gender',
                        'mobile', 'city_id', 'city_name', 'address', 'patient_diseases_id',
                        'last_clinic_time', 'clinic_id', 'belong_assistant_id', 'reg_time', 'last_revisiting_time',
                        'missed_days', 'revisiting_count', 'status', 'modify_time',
                        'outpatient_type_id', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }
        return true;
    }

    /**
     * 根据出生日期获取年龄
     * @param $birthDate string 出生日期【格式：2019-01-01】
     * @return float|int
     */
    public static function getAgeByBirthDate($birthDate)
    {
        if (!$birthDate) {
            return 0;
        }

        list($year, $month, $day) = explode('-', $birthDate);
        list($nowYear, $nowMonth, $nowDay) = explode('-', date('Y-m-d'));

        $diffYear = $nowYear - $year;
        $diffMonth = $nowMonth - $month;
        $diffDay = $nowDay - $day;
        // 月份不足or天份不足
        if ($diffMonth < 0 || ($diffMonth >= 0 && $diffDay < 0)) {
            $diffYear--;
        }
        return $diffYear >= 0 ? $diffYear : 0;
    }

    /**
     * 获取患者病种
     *
     * @Interface getPatientDisease
     */
    public static function getPatientDisease($patientId)
    {
        Model::setTableName('bm_case_record');
        $patientDisease = Model::find()
            ->select('patient_id, disease_id')
            ->where(['patient_id' => $patientId])
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        if ($patientDisease) {
            return $patientDisease['disease_id'];
        }
        return 0;
    }

    /**
     * 获取患者治疗部位
     *
     * @Interface getPatientBodyParts
     * @param $patientId
     * @return mixed|string
     */
    public static function getPatientBodyParts($patientId)
    {
        Model::setTableName('bm_treat_report');
        $patientParts = Model::find()
            ->select('patient_id, part')
            ->where(['patient_id' => $patientId])
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        if ($patientParts) {
            return $patientParts['part'];
        }
        return '';
    }

    /**
     * 最后一次治疗信息
     *
     * @Interface getPatientLastClinicTime
     * @param $patientId
     * @return int|mixed
     */
    public static function getPatientLastClinicTime($patientId)
    {
        Model::setTableName('bm_treat');
        $patientClinicTime = Model::find()
            ->select('patient_id, finished_at')
            ->where(['patient_id' => $patientId])
            ->andWhere(['>', 'finished_at', 0])
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        if ($patientClinicTime) {
            return $patientClinicTime['finished_at'];
        }
        return 0;
    }

    /**
     * 患者诊室(预约表最后一条诊室) / 患者第一次到诊(预约表第一条创建时间) 状态在1,3中
     *
     * @Interface getPatientClinicOrReg
     * @param $patientId
     * @return int|mixed
     */
    public static function getPatientClinicOrReg($patientId, $order)
    {
        if ($order == 1) {
            $orserIs = 'id desc';
        } else {
            $orserIs = 'id asc';
        }
        Model::setTableName('bm_patient_appoint_info');
        $patientClinicOrReg = Model::find()
            ->select('patient_id, clinic_id, clinic_name, created_at')
            ->where(['patient_id' => $patientId, 'appoint_status' => [1, 3]])
            ->orderBy($orserIs)
            ->limit(1)
            ->asArray()
            ->one();
        if ($patientClinicOrReg) {
            if ($order == 1) {
                $clinicIs = Clinic::findOne([
                    'name' => $patientClinicOrReg['clinic_name'],
                    'project_id' => 13,
                ]);
                // 患者诊室(预约表最后一条诊室)，诊室名称和白白管家一致时，返回白友诊室ID
                if ($clinicIs) {
                    return $clinicIs->id;
                }
                return 0;
            } else {
                return $patientClinicOrReg['created_at'];
            }
        }
        return 0;
    }

    /**
     * 患者来院次数
     *
     * @Interface patientRevisitingCount
     * @param $patientId
     * @return int|string
     */
    public static function patientRevisitingCount($patientId)
    {
        Model::setTableName('bm_patient_appoint_info');
        return Model::find()
            ->select('id')
            ->where(['patient_id' => $patientId, 'appoint_status' => [1, 3]])
            ->count();
    }

    //===============================================================================================

    /**
     * 患者病历数据
     */
    public static function case($lastPatientId, $params)
    {
        $startTime = $params['start_time'];
        $endTime = $params['end_time'];

        Model::setTableName('bm_case_record');
        $baibaiCase = Model::find()
            ->select('patient_id, id')
            ->where(['between', 'created_at', $startTime, $endTime])
            ->groupBy('patient_id')
            ->asArray()
            ->all();

        $addList = [];
        foreach ($baibaiCase as $val) {

            $patientTreatNo = self::havePatient($val['patient_id']);
            $baiyouPatient = User::findOne(['patient_card_id' => $patientTreatNo]);

            $patientMedical = MedicalRecords::findOne(['patient_user_id' => $baiyouPatient['id']]);

            // 患者病历不存在直接新增
            if (!$patientMedical) {
                Model::setTableName('bm_case_record');
                $caseIs = Model::find()
                    ->where(['patient_id' => $val['patient_id']])
                    ->orderBy('id desc')
                    ->limit(1)
                    ->asArray()
                    ->one();
                $add['project_id'] = self::$projectId;
                $add['patient_user_id'] = $lastPatientId + $val['patient_id'];
                $add['sick_time'] = $caseIs['ill_time'] ?? '';
                $add['main_desc'] = $caseIs['main_complain'] ?? '';
                $add['now_medical_history'] = $caseIs['present_history'] ?? '';
                $add['allergy_history'] = $caseIs['allergy_history'] ?? '';
                $add['jw_history'] = $caseIs['past_history'];
                $add['person_history'] = $caseIs['personal_history'];
                $add['family_history'] = $caseIs['family_history'];
                $add['physique_history'] = !empty($caseIs['body_check']) ? $caseIs['body_check'] : '';
                $add['diagnose'] = $caseIs['diseases_name'] ?? '';
                $add['auxiliary_result'] = $caseIs['assist_check_result'] ?? '';
                $add['clinic_opinion'] = $caseIs['treat_opinion'] ?? '';
                $add['patient_diseases_id'] = self::getDisease($caseIs['disease_id']) ?? 0;
                $add['diseases_name'] = $caseIs['disease_name'];
                $add['operate_id'] = self::createMember($caseIs['created_user_id']);
                $add['created_at'] = time();
                $add['updated_at'] = time();
                $addList[] = $add;
            } else {
                Model::setTableName('bm_case_record');
                $caseIs = Model::find()
                    ->where(['patient_id' => $val['patient_id']])
                    ->orderBy('id desc')
                    ->limit(1)
                    ->asArray()
                    ->one();

                // 病例创建时间 > 导入的开始时间
                if ($caseIs && isset($caseIs->created_at) && $caseIs->created_at >= $startTime) {
                    $patientMedical->main_desc = $caseIs['main_complain'];
                    $patientMedical->now_medical_history = $caseIs['present_history'];
                    $patientMedical->allergy_history = $caseIs['allergy_history'] ?? '';
                    $patientMedical->jw_history = $caseIs['past_history'];
                    $patientMedical->person_history = $caseIs['personal_history'];
                    $patientMedical->family_history = $caseIs['family_history'];
                    $patientMedical->physique_history = !empty($caseIs['body_check']) ? $caseIs['body_check'] : '';
                    $patientMedical->diagnose = $caseIs['diseases_name'] ?? '';
                    $patientMedical->auxiliary_result = $caseIs['assist_check_result'] ?? '';
                    $patientMedical->clinic_opinion = $caseIs['treat_opinion'] ?? '';
                    $patientMedical->patient_diseases_id = self::getDisease($caseIs['disease_id']) ?? 0;
                    $patientMedical->diseases_name = $caseIs['disease_name'];
                    $patientMedical->operate_id = self::createMember($caseIs['created_user_id']);
                    if (!$patientMedical->save()) {
                        throw new \Exception(json_encode($patientMedical->errors), 500);
                    }
                }
            }
        }

        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(MedicalRecords::tableName(),
                    [
                        'project_id', 'patient_user_id', 'sick_time', 'main_desc', 'now_medical_history', 'allergy_history',
                        'jw_history', 'person_history', 'family_history', 'physique_history', 'diagnose', 'auxiliary_result',
                        'clinic_opinion', 'patient_diseases_id', 'diseases_name', 'operate_id', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }
        return true;
    }


    //===================================================================================================

    /**
     * 患者治疗
     */
    public static function treat($params)
    {
        $startTime = $params['start_time'];
        $endTime = $params['end_time'];

        $whereTre = ['and'];
        $whereTre[] = ['between', 'created_at', $startTime, $endTime];
        $whereTre[] = ['=', 'status', 1];

        // 按时间的所有治疗数据
        Model::setTableName('bm_treat');
        $baibaiTreat = Model::find()
            ->where($whereTre)
            ->asArray()
            ->all();

        // 新增的治疗数据条数
        $newbaibaiTreat = count($baibaiTreat);

        // 白友用户治疗信息条数
        $haveTreatment = UserTreatment::find()
            ->where([
                'and',
                ['between', 'recently_clinic_time', $startTime, $endTime],
                ['project_id' => self::$projectId],
            ])
            ->count();

        $needUpdate = $newbaibaiTreat - $haveTreatment;

        // 如果所有数据都是已存在的，则直接返回
        if ($needUpdate <= 0) {
            return true;
        }
        $lastTreatment = UserTreatment::find()
            ->select('id')
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        $lastTreatmentId = 0;
        if ($lastTreatment && $lastTreatment['id']) {
            $lastTreatmentId = $lastTreatment['id'];
        }

        // 治疗数据新增部分ID， 然后移除已新增的，得到需要新增的treat_id
        $baibaiTreatIds = array_column($baibaiTreat, 'id');
        array_splice($baibaiTreatIds, 0, $haveTreatment);

        // 新增患者治疗详情
        self::treatDetail($lastTreatmentId, $baibaiTreatIds);

        $addList = [];
        foreach ($baibaiTreat as $key => $val) {

            // 如果存在已经同步的数据，则跳过
            if ($key + 1 <= $haveTreatment) {
                unset($baibaiTreat[$key]);
                continue;
            }

            Model::setTableName('bm_patient');
            $baibaiPatient = Model::findOne(['id' => $val['patient_id']]);

            $add['id'] = $val['id'] + $lastTreatmentId; // 治疗表没数据直接添加ID
            $add['project_id'] = self::$projectId;
            $add['treatment_room_id'] = self::getTreatmentRoom($val['consultroom_id']);
            $add['patient_card_id'] = $baibaiPatient->treat_no;

            $clinicProject = self::getClinicProject($val['item_id']);
            $add['clinic_project_id'] = $clinicProject['id'];
            $add['clinic_project_name'] = $clinicProject['name'];

            $add['recently_clinic_time'] = $val['finished_at'];
            $add['recently_clinic_num'] = $val['real_num'];
            $add['recently_surplus_num'] = 0;
            $add['clinic_id'] = self::getPatientClinicOrReg($val['patient_id'], 1);
            $add['clinic_name'] = ConfigService::CLINIC['name'];
            $add['operate_id'] = self::createMember($val['finished_user_id']);
            $add['operate_profession'] = '医助';
            $add['operate_name'] = $val['finished_user_name'];
            $add['patient_signature'] = $val['sign'];
            $add['type'] = UserTreatment::TYPE_TREAT;
            $add['remark'] = $val['doctor_remark'] . '/' . $val['treat_remark'];
            $add['created_at'] = time();
            $add['updated_at'] = time();
            $addList[] = $add;
        }

        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(UserTreatment::tableName(),
                    [
                        'id', 'project_id', 'treatment_room_id', 'patient_card_id', 'clinic_project_id',
                        'clinic_project_name', 'recently_clinic_time', 'recently_clinic_num', 'recently_surplus_num',
                        'clinic_id', 'clinic_name','operate_id', 'operate_profession', 'operate_name',
                        'patient_signature', 'type', 'remark','created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }
        return true;
    }

    /**
     *  患者治疗详情
     */
    public static function treatDetail($lastTreatmentId, $needBaibaiTreatIds)
    {
        Model::setTableName('bm_treat_info');
        $baibaiTreatInfo = Model::find()
            ->where(['treat_id' => $needBaibaiTreatIds])
            ->asArray()
            ->all();

        $lastTreatmentDetail = UserTreatmentDetail::find()
            ->select('id')
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        $lastTreatmentDetailId = 0;
        if ($lastTreatmentDetail && $lastTreatmentDetail['id']) {
            $lastTreatmentDetailId = $lastTreatmentDetail['id'];
        }

        $addList = [];
        foreach ($baibaiTreatInfo as $val) {

                Model::setTableName('bm_treat');
                $baibaiTreat = Model::find()
                    ->select('patient_id')
                    ->where(['id' => $val['treat_id']])
                    ->asArray()
                    ->one();

                Model::setTableName('bm_patient');
                $baibaiPatient = Model::findOne(['id' => $baibaiTreat['patient_id']]);

                $add['id'] = $val['id'] + $lastTreatmentDetailId; // 治疗表没数据直接添加ID
                $add['project_id'] = self::$projectId;
                $add['patient_card_id'] = $baibaiPatient->treat_no;
                $add['clinic_treatment_id'] = $val['treat_id'] + $lastTreatmentId;
                $add['body_parts_large_name'] = $val['body_large_name'];
                $add['body_parts_small_name'] = $val['body_small_name'];
                $add['num'] = $val['num'];
                $add['dose'] = $val['dose'];
                $add['created_at'] = time();
                $add['updated_at'] = time();
                $addList[] = $add;

        }
        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(UserTreatmentDetail::tableName(),
                    [
                        'id', 'project_id', 'patient_card_id', 'clinic_treatment_id', 'body_parts_large_name',
                        'body_parts_small_name', 'num', 'dose', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }
        return true;
    }

    /**
     * 患者治疗项目
     */
    public static function userSurplus($params)
    {
        $whereArr = ['or'];
        $whereArr[] = ['between', 'created_at', $params['start_time'], $params['end_time']];
        $whereArr[] = ['between', 'updated_at', $params['start_time'], $params['end_time']];

        Model::setTableName('bm_patient_item');
        $baibaiBillInfo = Model::find()
            ->where($whereArr)
            ->asArray()
            ->all();

        $addList = [];
        foreach ($baibaiBillInfo as $val) {

            Model::setTableName('bm_patient');
            $baibaiPatient = Model::findOne(['id' => $val['patient_id']]);

            $clinicProject = self::getClinicProject($val['item_id']);
            if (!isset($clinicProject['id'])) {
                continue;
            }

            $clinicProject = self::getClinicProject($val['item_id']);
            $userSurplusIs = UserSurplus::findOne([
                'patient_card_id' => $baibaiPatient->treat_no,
                'clinic_project_id' => $clinicProject['id']
            ]);

            if (!$userSurplusIs) {
                $add['project_id'] = self::$projectId;
                $add['patient_card_id'] = $baibaiPatient->treat_no;
                $add['name'] = $baibaiPatient->real_name;

                $clinicProject = self::getClinicProject($val['item_id']);
                $add['clinic_project_id'] = $clinicProject['id'];

                $add['clinic_project_name'] = $val['item_name'];
                $add['total_num'] = $val['remain_num'];// 这个数量是实际剩余数量，不用减
                $add['help_num'] = 0;
                $add['created_at'] = time();
                $add['updated_at'] = time();
                $addList[] = $add;
            } else {
                $userSurplusIs->total_num = $val['remain_num'];// 这个数量是实际剩余数量，不用减
                $userSurplusIs->updated_at = time();
                if (!$userSurplusIs->save()) {
                    throw new \Exception(json_encode($userSurplusIs->errors), 500);
                }
            }
        }
        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(UserSurplus::tableName(),
                    [
                        'project_id', 'patient_card_id', 'name', 'clinic_project_id', 'clinic_project_name',
                        'total_num', 'help_num', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }
        return true;
    }

    //=====================================================================================================

    /**
     * 患者就诊记录表(患者到院)
     */
    public static function clinicRecord($lastPatientId, $params)
    {
        Model::setTableName('bm_patient');
        $baibaiPatient = Model::find()
            ->alias('a')
            ->select('a.id')
            ->leftJoin('bm_treat', 'bm_treat.patient_id = a.id')
            ->leftJoin('bm_patient_appoint_info', 'bm_patient_appoint_info.patient_id = a.id')
            ->where(['between', 'bm_treat.created_at', $params['start_time'], $params['end_time']])
            ->orWhere(['between', 'bm_patient_appoint_info.in_time', $params['start_time'], $params['end_time']])
            ->asArray()
            ->all();

        $addList = [];
        $patientArrive = [];
        foreach ($baibaiPatient as $val) {

            // 患者治疗
            Model::setTableName('bm_treat');
            $baibaiTreatPatient = Model::find()
                ->select('id, patient_id, created_at, created_date')
                ->where(['status' => 1, 'patient_id' => $val['id']])
                ->andWhere(['between', 'created_at', $params['start_time'], $params['end_time']])
                ->groupBy('created_date')
                ->asArray()
                ->all();
            $createdDate = array_column($baibaiTreatPatient, 'created_date');

            // 患者到诊
            Model::setTableName('bm_patient_appoint_info');
            $baibaiAppointPatient = Model::find()
                ->select("id, patient_id, in_time")
                ->where(['appoint_status' => 3, 'patient_id' => $val['id']])
                ->andWhere(['between', 'in_time', $params['start_time'], $params['end_time']])
                ->asArray()
                ->all();

            // 格式调整
            foreach ($baibaiAppointPatient as $a => &$ap) {
                $ap['created_date'] = date('Y-m-d', $ap['in_time']);
                // 去重（一天一条数据）
                if (in_array($ap['created_date'], $createdDate)) {
                    unset($baibaiTreatPatient[$a]);
                    continue;
                }
                $ap['created_at'] = $ap['in_time'];
                unset($ap['in_time']);
            }

            $patientArrive = array_merge($patientArrive, $baibaiAppointPatient, $baibaiTreatPatient);
        }

        if ($patientArrive) {
            foreach ($patientArrive as $arrive) {

                $patientTreatNo = self::havePatient($arrive['patient_id']);
                $baiyouPatient = User::findOne(['patient_card_id' => $patientTreatNo]);

                // 判断是否为已存在患者
                if ($baiyouPatient) {
                    $patientId = $baiyouPatient->id;
                } else {
                    $patientId = $lastPatientId + $arrive['patient_id'];
                }

                // 判断当天记录是否存在
                $clinicRecordIs = ClinicRecord::findOne(['patient_user_id' => $patientId, 'clinic_day' => $arrive['created_date']]);
                if ($clinicRecordIs) {
                    continue;
                }

                $add['project_id'] = self::$projectId;
                $add['patient_user_id'] = $patientId;
                $add['clinic_day'] = $arrive['created_date'];
                $add['clinic_time'] = $arrive['created_at'] ?? 0;
                $add['is_initial_clinic'] = 0;// 初复诊
                $add['source'] = 3;// 来源白白管家
                $add['created_at'] = time();
                $add['updated_at'] = time();
                $addList[] = $add;
            }
        }

        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(ClinicRecord::tableName(),
                    [
                        'project_id', 'patient_user_id', 'clinic_day', 'clinic_time',
                        'is_initial_clinic', 'source', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }
        return true;
    }

    //=====================================================================================================
    /**
     * 患者消费记录表
     */
    public static function patientConsumption($params)
    {
        // 消费当天新数据
        Model::setTableName('bm_bill');
        $baibaiBill = Model::find()
            ->where(['patient_appoint_info_id' => 0, 'status' => 1])
            ->andWhere(['between', 'end_time', $params['start_time'], $params['end_time']])
            ->asArray()
            ->all();

        $baibaiBillCount = count($baibaiBill);

        $consumptionCount = Consumption::find()
            ->where([
                'and',
                ['between', 'clinic_time', $params['start_time'], $params['end_time']],
                ['project_id' => self::$projectId],
            ])
            ->asArray()
            ->count();

        $needUpdate = $baibaiBillCount - $consumptionCount;

        // 如果所有数据都是已存在的，则直接返回
        if ($needUpdate <= 0) {
            return true;
        }
        $lastConsumption = Consumption::find()
            ->select('id')
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        $consumptionId = 0;
        if ($lastConsumption && $lastConsumption['id']) {
            $consumptionId = $lastConsumption['id'];
        }

        // 消费当天新数据ID， 然后移除已新增的，得到需要新增的treat_id
        $newBillIds = array_column($baibaiBill, 'id');
        array_splice($newBillIds, 0, $consumptionCount);

        // 先新增消费详情
        self::patientConsumptionDetail($consumptionId, $newBillIds);

        $addList = [];
        foreach ($baibaiBill as $key => $val) {

            // 如果存在已经同步的数据，则跳过
            if ($key + 1 <= $consumptionCount) {
                unset($baibaiBill[$key]);
                continue;
            }

            Model::setTableName('bm_patient');
            $baibaiPatient = Model::findOne(['id' => $val['patient_id']]);

            $add['id'] = $lastConsumption ? ($lastConsumption['id'] + $val['id']) : $val['id'];
            $add['project_id'] = self::$projectId;
            $add['patient_card_id'] = $baibaiPatient->treat_no;

            // 消费表诊室ID增加
            $clinicIs = Clinic::findOne(['name' => $val['clinic_name']]);
            $add['clinic_id'] = 0;
            if ($clinicIs && $clinicIs->id) {
                $add['clinic_id'] = $clinicIs->id;
            }
            $add['consulting_room'] = $val['clinic_name'];
            $add['doctor_name'] = $val['doctor_real_name'] ?? '';
            $add['clinic_time'] = $val['reception_time'] ?? 0;

            if ($val['type'] == 1) { // 收费单
                $add['money'] = $val['all_cost'];
                $add['reality_money'] = $val['cost'];
                $add['refund_money'] = 0;
            } else { // 退费单
                $add['money'] = 0;
                $add['reality_money'] = -$val['cost'];
                $add['refund_money'] = -$val['cost'];
            }

            $add['trade_type'] = $val['type'];
            $add['remark'] = '';
            $add['created_at'] = time();
            $add['updated_at'] = time();
            $addList[] = $add;
        }

        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(Consumption::tableName(),
                    [
                        'id', 'project_id', 'patient_card_id', 'clinic_id', 'consulting_room', 'doctor_name', 'clinic_time',
                        'money', 'reality_money', 'refund_money', 'trade_type', 'remark', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }
        return true;
    }

    /**
     * 患者消费记录表
     */
    public static function patientConsumptionDetail($consumptionId, $newBillIds)
    {
        Model::setTableName('bm_bill_info');
        $baibaiBillInfo = Model::find()
            ->where(['>', 'id', 0])
            ->where(['bill_id' => $newBillIds])
            ->asArray()
            ->all();

        $addList = [];
        foreach ($baibaiBillInfo as $val) {

            Model::setTableName('bm_bill');
            $baibaiBill = Model::find()
                ->select('end_time, patient_id')
                ->where(['id' => $val['bill_id']])
                ->asArray()
                ->one();

            Model::setTableName('bm_patient');
            $baibaiPatient = Model::findOne(['id' => $baibaiBill['patient_id']]);

            $add['project_id'] = self::$projectId;
            $add['consumption_id'] = $consumptionId + $val['bill_id'];
            $add['patient_card_id'] = $baibaiPatient->treat_no;

            $add['yiyuan_aid'] = $val['id'];
            $add['drug_name'] = $val['treat_name'];
            $add['drug_num'] = $val['num'];
            $add['drug_unit'] = $val['unit'];
            $add['drug_type'] = $val['type'];
            $add['price'] = $val['price'];
            $add['money'] = $val['cost'];
            $add['discount_rate'] = 1;
            $add['reality_money'] = $val['cost'];
            $add['consumption_type'] = 1;
            $add['remark'] = '';
            $add['event_at'] = $baibaiBill['end_time'];

            $add['created_at'] = time();
            $add['updated_at'] = time();
            $addList[] = $add;
        }
        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(ConsumptionDetail::tableName(),
                    [
                        'project_id', 'consumption_id', 'patient_card_id', 'yiyuan_aid', 'drug_name',
                        'drug_num', 'drug_unit', 'drug_type', 'price', 'money', 'discount_rate', 'reality_money',
                        'consumption_type', 'remark', 'event_at', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }
        return true;
    }

    //=========================================================================================
    /**
     * 患者诊疗号重复(在患者已有诊疗号后加ID，只针对诊疗号为 7310119072902、7310119072905)
     * $patientId 白白管家患者表ID 3,4,5 => 7310119072902  8,9 => 7310119072905
     */
    public static function havePatient($patientId)
    {
        if ($patientId == 3) {
            return $treatNo = 73101190729023;
        } else if ($patientId == 4) {
            return $treatNo = 73101190729024;
        } elseif ($patientId == 5) {
            return $treatNo = 73101190729025;
        } elseif ($patientId == 8) {
            return $treatNo = 73101190729058;
        } elseif ($patientId == 9)  {
            return $treatNo = 73101190729059;
        } else {
            Model::setTableName('bm_patient');
            $patientUser = Model::findOne(['id' => $patientId]);
            return $patientUser->treat_no ?? 0;
        }
    }


    /**
     * 新增后台人员(操作人员不存在则新增)
     */
    public static function createMember($memberId)
    {
        Model::setTableName('bm_admin');
        $adminIs = Model::findOne(['user_id' => $memberId]);

        $memberIs = Member::find()
            ->alias('a')
            ->leftJoin(Attr::tableName() . ' b', 'a.id = b.member_id')
            ->where(['a.realname' => $adminIs->name, 'b.project_id' => self::$projectId])
            ->one();
        if (!$memberIs) {
            Model::setTableName('bm_admin');
            $admin = Model::findOne(['name' => $adminIs->name]);

            $member = new Member();
            $member->username = $admin->name;
            $member->mobile = $admin->phone;
            $member->password_hash = '$2y$13$89Wn/gAB9AQrjYxzm141U.Kpw6nOhiU17KwzoOPI0jYmXtH5A5O0O';
            $member->realname = $admin->name;
            $member->is_super = Member::IS_SUPER_NO;
            $member->save();

            $attr = new Attr();
            $attr->member_id = $member->id;
            $attr->project_id = self::$projectId;
            $attr->department_id = 85;
            $attr->clinic_id = ConfigService::CLINIC['id'];
            $attr->profession_id = 301;
            $attr->profession_name = '医助';
            $attr->save();

            return $member->id;
        }
        return $memberIs->id;
    }

    /**
     * 获取大部位
     *
     * @param $largeBodyId
     * @return int
     */
    public static function getLargeBody($largeBodyId)
    {
        Model::setTableName('bm_body_large');
        $baibaiLargeBody = Model::findOne(['id' => $largeBodyId]);

        if (!$baibaiLargeBody || !$baibaiLargeBody->name) {
            return 0;
        }
        $baiyouLargeBody = BodyParts::findOne(['body_parts_name' => $baibaiLargeBody->name, 'pid' => 0]);
        return $baiyouLargeBody->id;
    }

    /**
     * 获取小部位
     *
     * @param $smallBodyId
     * @return int
     */
    public static function getSmallBody($smallBodyId)
    {
        Model::setTableName('bm_body_small');
        $baibaiSmallBody = Model::find()
            ->where(['id' => $smallBodyId])
            ->asArray()
            ->one();

        Model::setTableName('bm_body_relation');
        $baibaiBodyRelation = Model::find()
            ->where(['body_small_id' => $smallBodyId])
            ->asArray()
            ->one();

        $baiyouSmallBody = BodyParts::findOne(['body_parts_name' => $baibaiSmallBody['name'], 'pid' => $baibaiBodyRelation['body_large_id']]);
        return $baiyouSmallBody->id ?? 0;
    }

    /**
     * 治疗室
     *
     * @param $treatmentRoomId
     * @return int
     */
    public static function getTreatmentRoom($treatmentRoomId)
    {
        Model::setTableName('bm_consultroom_config');
        $baibaiTreatmentRoom = Model::findOne(['id' => $treatmentRoomId]);

        if (!$baibaiTreatmentRoom || !$baibaiTreatmentRoom->name) {
            return 0;
        }
        $baiyouTreatmentRoom = TreatmentRoom::findOne(['project_id' => self::$projectId, 'name' => $baibaiTreatmentRoom->name]);
        return $baiyouTreatmentRoom->id ?? 0;
    }

    /**
     * 治疗项目
     *
     * @param $clinicProjectId
     * @return array
     */
    public static function getClinicProject($clinicProjectId)
    {
        Model::setTableName('bm_item');
        $baibaiclinicProject = Model::findOne(['id' => $clinicProjectId]);

        if (!$baibaiclinicProject || !$baibaiclinicProject->name) {
            return ['id' => 0, 'name' => ''];
        }
        $baiyouclinicProject = Project::findOne(['project_id' => self::$projectId, 'name' => $baibaiclinicProject->name]);
        // 如果不存在则新建
        if (!$baiyouclinicProject) {
            $baiyouclinicProject = new Project();
            $baiyouclinicProject->name = $baibaiclinicProject->name;
            $baiyouclinicProject->project_id = self::$projectId;
            $baiyouclinicProject->bind_yiyuan_name = $baibaiclinicProject->name;
            $baiyouclinicProject->status = Project::STATUS_ENABLE;
            $baiyouclinicProject->template = $baibaiclinicProject->treat_template ? $baibaiclinicProject->treat_template : 3;
            $baiyouclinicProject->created_at = time();
            $baiyouclinicProject->updated_at = time();
            $baiyouclinicProject->save();
        }
        return ['id' => $baiyouclinicProject->id ?? 0, 'name' => $baiyouclinicProject->name ?? ''];
    }

    /**
     * 病种
     *
     * @param $diseaseId
     * @return int
     */
    public static function getDisease($diseaseId)
    {
        Model::setTableName('bm_disease');
        $baibaiDisease = Model::findOne(['id' => $diseaseId]);

        if (!$baibaiDisease || !$baibaiDisease->name) {
            return 0;
        }
        $baiyouDisease = PatientDiseases::findOne(['pid' => 0, 'diseases_name' => $baibaiDisease->name]);
        return $baiyouDisease->id ?? 0;
    }

    /**
     * 患者消费、治疗、来院记录表
     *
     * @param $params
     * @return bool|int
     */
    public static function patientRevisitingRecordTreat($params)
    {
        $startTime = $params['start_time'];

        $endTime = $params['end_time'];

        $whereTre = ['and'];
        $whereTre[] = ['between', 'created_at', $startTime, $endTime];
        $whereTre[] = ['=', 'status', 1];

        // 按时间的所有治疗数据
        Model::setTableName('bm_treat');
        $baibaiTreat = Model::find()
            ->where($whereTre)
            ->asArray()
            ->all();

        // 新增的治疗数据条数
        $newbaibaiTreat = count($baibaiTreat);

        // 白友用户治疗信息条数
        $haveTreatment = RevisitingRecord::find()
            ->where([
                'and',
                ['between', 'revisting_time', $startTime, $endTime],
                ['project_id' => self::$projectId, 'type' => RevisitingRecord::TYPE_TREAT],
            ])
            ->count();

        $needUpdate = $newbaibaiTreat - $haveTreatment;

        // 如果所有数据都是已存在的，则直接返回
        if ($needUpdate <= 0) {
            return true;
        }
        $lastTreatment = RevisitingRecord::find()
            ->select('id')
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        $lastTreatmentId = 0;
        if ($lastTreatment && $lastTreatment['id']) {
            $lastTreatmentId = $lastTreatment['id'];
        }

        // 治疗数据新增部分ID， 然后移除已新增的，得到需要新增的treat_id
        $baibaiTreatIds = array_column($baibaiTreat, 'id');
        array_splice($baibaiTreatIds, 0, $haveTreatment);

        $addList = [];
        foreach ($baibaiTreat as $key => $val) {

            // 如果存在已经同步的数据，则跳过
            if ($key + 1 <= $haveTreatment) {
                unset($baibaiTreat[$key]);
                continue;
            }

            Model::setTableName('bm_patient');
            $baibaiPatient = Model::findOne(['id' => $val['patient_id']]);

            $add['id'] = $val['id'] + $lastTreatmentId; // 治疗表没数据直接添加ID
            $add['project_id'] = self::$projectId;
            $add['clinic_id'] = self::getPatientClinicOrReg($val['patient_id'], 1);
            $add['patient_card_id'] = $baibaiPatient->treat_no;
            $add['revisting_time'] = $val['created_at'];
            $add['source_id'] = $val['id'];
            $add['type'] = RevisitingRecord::TYPE_TREAT;

            $add['is_sum'] = RevisitingRecord::IS_SUM_NO;
            $add['day_time'] = strtotime($val['created_date']);

            $add['created_at'] = time();
            $add['updated_at'] = time();
            $addList[] = $add;
        }

        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(RevisitingRecord::tableName(),
                    [
                        'id', 'project_id', 'clinic_id', 'patient_card_id', 'revisting_time',
                        'source_id', 'type', 'is_sum', 'day_time', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }

        return true;

    }


    /**
     * 患者消费、治疗、来院记录表
     *
     * @param $params
     * @return bool|int
     */
    public static function patientRevisitingRecordBill($params)
    {
        $startTime = $params['start_time'];

        $endTime = $params['end_time'];

        $whereTre = ['and'];
        $whereTre[] = ['between', 'created_at', $startTime, $endTime];
        $whereTre[] = ['patient_appoint_info_id' => 0, 'status' => 1];

        // 按时间的所有消费数据
        Model::setTableName('bm_bill');
        $baibaibill = Model::find()
            ->where($whereTre)
            ->asArray()
            ->all();

        // 新增的消费数据条数
        $newbaibaibill = count($baibaibill);

        // 白友用户消费信息条数
        $havebill = RevisitingRecord::find()
            ->where([
                'and',
                ['between', 'revisting_time', $startTime, $endTime],
                ['project_id' => self::$projectId, 'type' => RevisitingRecord::TYPE_CONSUME],
            ])
            ->count();

        $needUpdate = $newbaibaibill - $havebill;

        // 如果所有数据都是已存在的，则直接返回
        if ($needUpdate <= 0) {
            return true;
        }
        $lastbill = RevisitingRecord::find()
            ->select('id')
            ->orderBy('id desc')
            ->limit(1)
            ->asArray()
            ->one();
        $lastbillId = 0;
        if ($lastbill && $lastbill['id']) {
            $lastbillId = $lastbill['id'];
        }

        // 消费数据新增部分ID， 然后移除已新增的，得到需要新增的treat_id
        $baibaibillIds = array_column($baibaibill, 'id');
        array_splice($baibaibillIds, 0, $havebill);

        $addList = [];
        foreach ($baibaibill as $key => $val) {

            // 如果存在已经同步的数据，则跳过
            if ($key + 1 <= $havebill) {
                unset($baibaibill[$key]);
                continue;
            }

            Model::setTableName('bm_patient');
            $baibaiPatient = Model::findOne(['id' => $val['patient_id']]);

            $add['id'] = $val['id'] + $lastbillId; // 消费表没数据直接添加ID
            $add['project_id'] = self::$projectId;
            $add['clinic_id'] = self::getPatientClinicOrReg($val['patient_id'], 1);;
            $add['patient_card_id'] = $baibaiPatient->treat_no;
            $add['revisting_time'] = $val['created_at'];
            $add['source_id'] = $val['id'];
            $add['type'] = RevisitingRecord::TYPE_CONSUME;

            $add['is_sum'] = RevisitingRecord::IS_SUM_NO;
            $add['day_time'] = strtotime($val['created_date']);

            $add['created_at'] = time();
            $add['updated_at'] = time();
            $addList[] = $add;
        }

        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(RevisitingRecord::tableName(),
                    [
                        'id', 'project_id', 'clinic_id', 'patient_card_id', 'revisting_time',
                        'source_id', 'type', 'is_sum', 'day_time', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }

        return true;

    }

    /**
     * 更新来院记录表的is_sum字段（一个患者一天只记录一次）
     *
     * @param $params
     * @return bool|int
     */
    public static function updateIsSum($params)
    {
        $revisitingRecord = RevisitingRecord::find()
            ->select('day_time, patient_card_id, id, project_id')
            ->where([
                'and',
                ['between', 'revisting_time', $params['start_time'], $params['end_time']],
                ['project_id' => self::$projectId],
            ])
            ->groupBy('day_time, patient_card_id')
            ->asArray()
            ->all();

        if ($revisitingRecord) {

            // 新增患者月到诊统计记录表
            self::createPatientMonthRevisitingRecord($params['start_time'], $params['end_time']);

            $updateIds = array_column($revisitingRecord, 'id');
            RevisitingRecord::updateAll(['is_sum' => RevisitingRecord::IS_SUM_YES], ['id' => $updateIds]);
            return true;
        }
        return true;
    }

    /**
     * 患者月到诊统计记录表
     *
     * @param $startTime
     * @param $endTime
     * @return bool|int
     */
    public static function createPatientMonthRevisitingRecord($startTime, $endTime)
    {
        // 按照患者诊疗号及月份分组
        $revisitingRecord = RevisitingRecord::find()
            ->select([
                'patient_card_id', 'id', 'project_id',
                new Expression('FROM_UNIXTIME(`day_time`, "%Y-%m") day_date'),
                'day_time',  'clinic_id'
            ])
            ->where([
                'and',
                ['between', 'revisting_time', $startTime, $endTime],
                ['project_id' => self::$projectId],
            ])
            ->groupBy('day_date, patient_card_id')
            ->orderBy(['id' => SORT_DESC])
            ->asArray()
            ->all();

        $addList = [];
        foreach ($revisitingRecord as $val) {
            if (MonthRevisitingRecord::findOne([
                'project_id' => $val['project_id'],
                'patient_card_id' => $val['patient_card_id'],
                'month' => $val['day_time']])) {
                continue;
            }

            $add['project_id'] = self::$projectId;
            $add['clinic_id'] = $val['clinic_id'];
            $add['patient_card_id'] = $val['patient_card_id'];
            $add['month'] = $val['day_time'];
            $add['status'] = MonthRevisitingRecord::STATUS_ENABLE;

            $add['created_at'] = time();
            $add['updated_at'] = time();
            $addList[] = $add;

        }
        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(MonthRevisitingRecord::tableName(),
                    [
                        'project_id', 'clinic_id', 'patient_card_id', 'month',
                        'status', 'created_at', 'updated_at'
                    ],
                    $addList)
                ->execute();
        }

        return true;

    }

}